

// phpDate.js
// 시간 데이터와 현재 시간을 비교하여 기존 sns와 같은 몇시간전, 몇일전, 해당 날짜를 표현하기 위한 라이브러리
// dinamicDate가 실제 활용하는 함수
// dateFormat은 원하는 포맷으로 데이터 형식을 변환시켜주는 도구함수

Date.prototype.getDOY = function() {
	var onejan = new Date(this.getFullYear(),0,1);
	return Math.ceil((this - onejan) / 86400000);
 
}

var dateFormat = function () {
	var	token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
		timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
		timezoneClip = /[^-+\dA-Z]/g,
		pad = function (val, len) {
			val = String(val);
			len = len || 2;
			while (val.length < len) val = "0" + val;
			return val;
		};

	// Regexes and supporting functions are cached through closure
	return function (date, mask, utc) {
		var dF = dateFormat;

		// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
		if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
			mask = date;
			date = undefined;
		}

		// Passing date through Date applies Date.parse, if necessary
		date = date ? new Date(date) : new Date;
		if (isNaN(date)) throw SyntaxError("invalid date");

		mask = String(dF.masks[mask] || mask || dF.masks["default"]);

		// Allow setting the utc argument via the mask
		if (mask.slice(0, 4) == "UTC:") {
			mask = mask.slice(4);
			utc = true;
		}

		var	_ = utc ? "getUTC" : "get",
			d = date[_ + "Date"](),
			D = date[_ + "Day"](),
			m = date[_ + "Month"](),
			y = date[_ + "FullYear"](),
			H = date[_ + "Hours"](),
			M = date[_ + "Minutes"](),
			s = date[_ + "Seconds"](),
			L = date[_ + "Milliseconds"](),
			o = utc ? 0 : date.getTimezoneOffset(),
			flags = {
				d:    d,
				dd:   pad(d),
				ddd:  dF.i18n.dayNames[D],
				dddd: dF.i18n.dayNames[D + 7],
				m:    m + 1,
				mm:   pad(m + 1),
				mmm:  dF.i18n.monthNames[m],
				mmmm: dF.i18n.monthNames[m + 12],
				yy:   String(y).slice(2),
				yyyy: y,
				h:    H % 12 || 12,
				hh:   pad(H % 12 || 12),
				H:    H,
				HH:   pad(H),
				M:    M,
				MM:   pad(M),
				s:    s,
				ss:   pad(s),
				l:    pad(L, 3),
				L:    pad(L > 99 ? Math.round(L / 10) : L),
				t:    H < 12 ? "a"  : "p",
				tt:   H < 12 ? "am" : "pm",
				T:    H < 12 ? "A"  : "P",
				TT:   H < 12 ? "AM" : "PM",
				Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
				o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
				S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
			};

		return mask.replace(token, function ($0) {
			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
		});
	};
}();

// Some common format strings
dateFormat.masks = {
	"default":      "ddd mmm dd yyyy HH:MM:ss",
	shortDate:      "m/d/yy",
	mediumDate:     "mmm d, yyyy",
	longDate:       "mmmm d, yyyy",
	fullDate:       "dddd, mmmm d, yyyy",
	shortTime:      "h:MM TT",
	mediumTime:     "h:MM:ss TT",
	longTime:       "h:MM:ss TT Z",
	isoDate:        "yyyy-mm-dd",
	isoTime:        "HH:MM:ss",
	isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
	isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

// Internationalization strings
dateFormat.i18n = {
	dayNames: [
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
	],
	monthNames: [
		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
		"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
	]
};

// For convenience...
Date.prototype.format = function (mask, utc) {
	return dateFormat(this, mask, utc);
};

function date (format, timestamp) {
    // *     example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
    // *     returns 1: '09:09:40 m is month'
    // *     example 2: date('F j, Y, g:i a', 1062462400);
    // *     returns 2: 'September 2, 2003, 2:26 am'
    // *     example 3: date('Y W o', 1062462400);
    // *     returns 3: '2003 36 2003'
    // *     example 4: x = date('Y m d', (new Date()).getTime()/1000); 
    // *     example 4: (x+'').length == 10 // 2009 01 09
    // *     returns 4: true
    // *     example 5: date('W', 1104534000);
    // *     returns 5: '53'
    // *     example 6: date('B t', 1104534000);
    // *     returns 6: '999 31'
    // *     example 7: date('W U', 1293750000.82); // 2010-12-31
    // *     returns 7: '52 1293750000'
    // *     example 8: date('W', 1293836400); // 2011-01-01
    // *     returns 8: '52'
    // *     example 9: date('W Y-m-d', 1293974054); // 2011-01-02
    // *     returns 9: '52 2011-01-02'
    var that = this,
        jsdate, f, formatChr = /\\?([a-z])/gi,
        formatChrCb,
        // Keep this here (works, but for code commented-out
        // below for file size reasons)
        //, tal= [],
        _pad = function (n, c) {
            if ((n = n + '').length < c) {
                return new Array((++c) - n.length).join('0') + n;
            }
            return n;
        },
        txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
    formatChrCb = function (t, s) {
        return f[t] ? f[t]() : s;
    };
    f = {
        // Day
        d: function () { // Day of month w/leading 0; 01..31
            return _pad(f.j(), 2);
        },
        D: function () { // Shorthand day name; Mon...Sun
            return f.l().slice(0, 3);
        },
        j: function () { // Day of month; 1..31
            return jsdate.getDate();
        },
        l: function () { // Full day name; Monday...Sunday
            return txt_words[f.w()] + 'day';
        },
        N: function () { // ISO-8601 day of week; 1[Mon]..7[Sun]
            return f.w() || 7;
        },
        S: function () { // Ordinal suffix for day of month; st, nd, rd, th
            var j = f.j();
            return j < 4 | j > 20 && ['st', 'nd', 'rd'][j%10 - 1] || 'th'; 
        },
        w: function () { // Day of week; 0[Sun]..6[Sat]
            return jsdate.getDay();
        },
        z: function () { // Day of year; 0..365
            var a = new Date(f.Y(), f.n() - 1, f.j()),
                b = new Date(f.Y(), 0, 1);
            return Math.round((a - b) / 864e5) + 1;
        },

        // Week
        W: function () { // ISO-8601 week number
            var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3),
                b = new Date(a.getFullYear(), 0, 4);
            return _pad(1 + Math.round((a - b) / 864e5 / 7), 2);
        },

        // Month
        F: function () { // Full month name; January...December
            return txt_words[6 + f.n()];
        },
        m: function () { // Month w/leading 0; 01...12
            return _pad(f.n(), 2);
        },
        M: function () { // Shorthand month name; Jan...Dec
            return f.F().slice(0, 3);
        },
        n: function () { // Month; 1...12
            return jsdate.getMonth() + 1;
        },
        t: function () { // Days in month; 28...31
            return (new Date(f.Y(), f.n(), 0)).getDate();
        },

        // Year
        L: function () { // Is leap year?; 0 or 1
            var j = f.Y();
            return j%4==0 & j%100!=0 | j%400==0;
        },
        o: function () { // ISO-8601 year
            var n = f.n(),
                W = f.W(),
                Y = f.Y();
            return Y + (n === 12 && W < 9 ? 1 : n === 1 && W > 9 ? -1 : 0);
        },
        Y: function () { // Full year; e.g. 1980...2010
            return jsdate.getFullYear();
        },
        y: function () { // Last two digits of year; 00...99
            return (f.Y() + "").slice(-2);
        },

        // Time
        a: function () { // am or pm
            return jsdate.getHours() > 11 ? "pm" : "am";
        },
        A: function () { // AM or PM
            return f.a().toUpperCase();
        },
        B: function () { // Swatch Internet time; 000..999
            var H = jsdate.getUTCHours() * 36e2,
                // Hours
                i = jsdate.getUTCMinutes() * 60,
                // Minutes
                s = jsdate.getUTCSeconds(); // Seconds
            return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3);
        },
        g: function () { // 12-Hours; 1..12
            return f.G() % 12 || 12;
        },
        G: function () { // 24-Hours; 0..23
            return jsdate.getHours();
        },
        h: function () { // 12-Hours w/leading 0; 01..12
            return _pad(f.g(), 2);
        },
        H: function () { // 24-Hours w/leading 0; 00..23
            return _pad(f.G(), 2);
        },
        i: function () { // Minutes w/leading 0; 00..59
            return _pad(jsdate.getMinutes(), 2);
        },
        s: function () { // Seconds w/leading 0; 00..59
            return _pad(jsdate.getSeconds(), 2);
        },
        u: function () { // Microseconds; 000000-999000
            return _pad(jsdate.getMilliseconds() * 1000, 6);
        },

        // Timezone
        e: function () { // Timezone identifier; e.g. Atlantic/Azores, ...
            // The following works, but requires inclusion of the very large
            // timezone_abbreviations_list() function.
/*              return that.date_default_timezone_get();
*/
            throw 'Not supported (see source code of date() for timezone on how to add support)';
        },
        I: function () { // DST observed?; 0 or 1
            // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
            // If they are not equal, then DST is observed.
            var a = new Date(f.Y(), 0),
                // Jan 1
                c = Date.UTC(f.Y(), 0),
                // Jan 1 UTC
                b = new Date(f.Y(), 6),
                // Jul 1
                d = Date.UTC(f.Y(), 6); // Jul 1 UTC
            return 0 + ((a - c) !== (b - d));
        },
        O: function () { // Difference to GMT in hour format; e.g. +0200
            var tzo = jsdate.getTimezoneOffset(),
                a = Math.abs(tzo);
            return (tzo > 0 ? "-" : "+") + _pad(Math.floor(a / 60) * 100 + a % 60, 4);
        },
        P: function () { // Difference to GMT w/colon; e.g. +02:00
            var O = f.O();
            return (O.substr(0, 3) + ":" + O.substr(3, 2));
        },
        T: function () { // Timezone abbreviation; e.g. EST, MDT, ...
            // The following works, but requires inclusion of the very
            // large timezone_abbreviations_list() function.
/*              var abbr = '', i = 0, os = 0, default = 0;
            if (!tal.length) {
                tal = that.timezone_abbreviations_list();
            }
            if (that.php_js && that.php_js.default_timezone) {
                default = that.php_js.default_timezone;
                for (abbr in tal) {
                    for (i=0; i < tal[abbr].length; i++) {
                        if (tal[abbr][i].timezone_id === default) {
                            return abbr.toUpperCase();
                        }
                    }
                }
            }
            for (abbr in tal) {
                for (i = 0; i < tal[abbr].length; i++) {
                    os = -jsdate.getTimezoneOffset() * 60;
                    if (tal[abbr][i].offset === os) {
                        return abbr.toUpperCase();
                    }
                }
            }
*/
            return 'UTC';
        },
        Z: function () { // Timezone offset in seconds (-43200...50400)
            return -jsdate.getTimezoneOffset() * 60;
        },

        // Full Date/Time
        c: function () { // ISO-8601 date.
            return 'Y-m-d\\TH:i:sP'.replace(formatChr, formatChrCb);
        },
        r: function () { // RFC 2822
            return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
        },
        U: function () { // Seconds since UNIX epoch
            return jsdate / 1000 | 0;
        }
    };
    this.date = function (format, timestamp) {
        that = this;
        jsdate = (timestamp == null ? new Date() : // Not provided
            (timestamp instanceof Date) ? new Date(timestamp) : // JS Date()
            new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
        );
        return format.replace(formatChr, formatChrCb);
    };
    return this.date(format, timestamp);
}

function dynamicDate(dt, option, nocalcserverdif){
	if (typeof timeDif == "undefined") timeDif = 0;
 
	if (!nocalcserverdif)
	{
		dt += timeDif;
	}
	var dif = Math.floor(new Date().getTime() / 1000) - dt;
 
	switch(option)
	{
		case "half":
			if (dif >= 0)
			{
				var today = new Date();
 
				var seconds = dif%60,
					minutes = ((dif-seconds)%3600)/60,
					hours = ((dif-(minutes*60+seconds))%86400)/3600;
 
				var days = today.getDOY() - date("z", dt),
					months = (today.getFullYear()*12 + today.getMonth() + 1) - (parseInt(date("Y",dt)*12) + parseInt(date("n", dt))),
					years = today.getFullYear() - date("Y", dt);
 
				if (years == 0 || (years == 1 && months <= 1))
				{
					if (months == 0 || (months == 1 && days < 7))
					{
						if (days == 0)
						{
							if (hours == 0)
							{
								if (minutes == 0)
								{
									if (seconds <= 2)
									{
										return "방금 전";
									}
									else
									{
										return seconds+"초 전";
									}
								}
								else
								{
									return minutes+"분 "+seconds+"초 전";
								}
							}
							else
							{
								return hours+"시간 "+minutes+"분 전";
							}
						}
						else if (days == 1)
						{
							return "어제 "+date("H시", dt);
						}
						else if (days == 2)
						{
							return "그저께 "+date("H시", dt);
						}
						else if (days == 3)
						{
							return "그끄저께 "+date("H시", dt);
						}
						else if (days < 7)
						{
							var weekStr = ['일','월','화','수','목','금','토'];
							return weekStr[date('w', dt)]+"요일 "+date("H시", dt);
						}
						else
						{
							return days+"일 전 "+date("H시", dt);
						}
					}
					else if (months == 1)
					{
						return "저번달 "+date("j일", dt);
					}
					else if (months < 6)
					{
						return months+"달 전 "+date("j일", dt);
					}
					else
					{
						return date("n월 j일", dt);
					}
				}
				else if (years == 1)
				{
					return "작년 "+date("n", dt)+"월 "+date("j일", dt);
				}
				else if (years == 2)
				{
					return "재작년 "+date("n", dt)+"월 "+date("j일", dt);
				}
				else
				{
					return years+"년 전 "+date("n", dt)+"월 "+date("j일", dt);
				}
			}
			else
			{
				dif = dif * -1;
				var today = new Date();
 
				var seconds = dif%60,
					minutes = ((dif-seconds)%3600)/60,
					hours = ((dif-(minutes*60+seconds))%86400)/3600;
 
				var days = date("z", dt) - today.getDOY(),
					months = (parseInt(date("Y",dt)*12) + parseInt(date("n", dt))) - (today.getFullYear()*12 + today.getMonth() + 1),
					years = date("Y", dt) - today.getFullYear();
 
				if (years == 0 || (years == 1 && months <= 1))
				{
					if (months == 0 || (months == 1 && days < 7))
					{
						if (days == 0)
						{
							if (hours == 0)
							{
								if (minutes == 0)
								{
									if (seconds <= 2)
									{
										return "곧";
									}
									else
									{
										return seconds+"초 후";
									}
								}
								else
								{
									return minutes+"분 "+seconds+"초 후";
								}
							}
							else
							{
								return hours+"시간 "+minutes+"분 후";
							}
						}
						else if (days == 1)
						{
							return "내일 "+date("H시", dt);
						}
						else if (days == 2)
						{
							return "모레 "+date("H시", dt);
						}
						else
						{
							return days+"일 후 "+date("H시", dt);
						}
					}
					else if (months == 1)
					{
						return "다음달 "+date("j일", dt);
					}
					else if (months < 6)
					{
						return months+"달 후 "+date("j일", dt);
					}
					else
					{
						return date("n월 j일", dt);
					}
				}
				else if (years == 1)
				{
					return "내년 "+date("n", dt)+"월 "+date("j일", dt);
				}
				else if (years == 2)
				{
					return "내후년 "+date("n", dt)+"월 "+date("j일", dt);
				}
				else
				{
					return years+"년 후 "+date("n", dt)+"월 "+date("j일", dt);
				}
			}
			break;
 
		default:
			if (dif >= 0)
			{
				var today = new Date();
 
				var seconds = dif%60,
					minutes = ((dif-seconds)%3600)/60,
					hours = ((dif-(minutes*60+seconds))%86400)/3600;
 
				var days = today.getDOY() - date("z", dt),
					months = (today.getFullYear()*12 + today.getMonth() + 1) - (parseInt(date("Y",dt)*12) + parseInt(date("n", dt))),
					years = today.getFullYear() - date("Y", dt);
 
				if (years == 0 || (years == 1 && months <= 1))
				{
					if (months == 0 || (months == 1 && days < 7))
					{
						if (days == 0)
						{
							if (hours == 0)
							{
								if (minutes == 0)
								{
									if (seconds <= 2)
									{
										return "방금 전";
									}
									else
									{
										return seconds+"초 전";
									}
								}
								else
								{
									return minutes+"분 "+seconds+"초 전";
								}
							}
							else
							{
								return hours+"시간 "+minutes+"분 전";
							}
						}
						else if (days == 1)
						{
							return "어제 "+date("H시 i분", dt);
						}
						else if (days == 2)
						{
							return "그저께 "+date("H시 i분", dt);
						}
						else if (days == 3)
						{
							return "그끄저께 "+date("H시 i분", dt);
						}
						else if (days < 7)
						{
							var weekStr = ['일','월','화','수','목','금','토'];
							return weekStr[date('w', dt)]+"요일 "+date("H시 i분", dt);
						}
						else
						{
							return days+"일 전 "+date("H시 i분", dt);
						}
					}
					else if (months == 1)
					{
						return "저번달 "+date("j일 H시", dt);
					}
					else if (months < 6)
					{
						return months+"달 전 "+date("j일 H시", dt);
					}
					else
					{
						return date("n월 j일 H시", dt);
					}
				}
				else if (years == 1)
				{
					return "작년 "+date("n", dt)+"월 "+date("j일 H시", dt);
				}
				else if (years == 2)
				{
					return "재작년 "+date("n", dt)+"월 "+date("j일 H시", dt);
				}
				else
				{
					return years+"년 전 "+date("n", dt)+"월 "+date("j일 H시", dt);
				}
			}
			else
			{
				dif = dif * -1;
				var today = new Date();
 
				var seconds = dif%60,
					minutes = ((dif-seconds)%3600)/60,
					hours = ((dif-(minutes*60+seconds))%86400)/3600;
 
				var days = date("z", dt) - today.getDOY(),
					months = (parseInt(date("Y",dt)*12) + parseInt(date("n", dt))) - (today.getFullYear()*12 + today.getMonth() + 1),
					years = date("Y", dt) - today.getFullYear();
 
				if (years == 0 || (years == 1 && months <= 1))
				{
					if (months == 0 || (months == 1 && days < 7))
					{
						if (days == 0)
						{
							if (hours == 0)
							{
								if (minutes == 0)
								{
									if (seconds <= 2)
									{
										return "곧";
									}
									else
									{
										return seconds+"초 후";
									}
								}
								else
								{
									return minutes+"분 "+seconds+"초 후";
								}
							}
							else
							{
								return hours+"시간 "+minutes+"분 후";
							}
						}
						else if (days == 1)
						{
							return "내일 "+date("H시 i분", dt);
						}
						else if (days == 2)
						{
							return "모레 "+date("H시 i분", dt);
						}
						else if (days < 7)
						{
							var weekStr = ['일','월','화','수','목','금','토'];
							return weekStr[date('w', dt)]+"요일 "+date("H시 i분", dt);
						}
						else
						{
							return days+"일 후 "+date("H시 i분", dt);
						}
					}
					else if (months == 1)
					{
						return "다음달 "+date("j일 H시", dt);
					}
					else if (months < 6)
					{
						return months+"달 후 "+date("j일 H시", dt);
					}
					else
					{
						return date("n월 j일 H시", dt);
					}
				}
				else if (years == 1)
				{
					return "내년 "+date("n", dt)+"월 "+date("j일 H시", dt);
				}
				else if (years == 2)
				{
					return "내후년 "+date("n", dt)+"월 "+date("j일 H시", dt);
				}
				else
				{
					return years+"년 후 "+date("n", dt)+"월 "+date("j일 H시", dt);
				}
			}
	}
}

